package com.second.util;

import com.second.model.dto.recommend.RecommendVo;
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.common.LongPrimitiveIterator;
import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;
import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.EuclideanDistanceSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 基于用户的协同过滤计算
 */
public class UserCF {
    final static int NEIGHBORHOOD_NUM = 3;//临近的用户个数
    final static int RECOMMENDER_NUM = 5;//推荐物品的最大个数

    public static List<RecommendVo> userRecommend(Integer userId) throws IOException, TasteException {
        //对应用户推荐列表
        List<RecommendVo> RecommendList = new ArrayList<>();
        String file = "src/data/UserCF.csv";
        DataModel model = new FileDataModel(new File(file));//数据模型

        UserSimilarity userSim = new EuclideanDistanceSimilarity(model);//用户相识度算法
        //用户近邻算法
        NearestNUserNeighborhood neighbor = new NearestNUserNeighborhood(NEIGHBORHOOD_NUM, userSim, model);

        Recommender r = new GenericUserBasedRecommender(model, neighbor, userSim);//用户推荐算法
        LongPrimitiveIterator iter = model.getUserIDs();///得到用户ID

        while (iter.hasNext()) {
            long uid = iter.nextLong();
            if (uid == userId){
                List<RecommendedItem> list = r.recommend(uid, RECOMMENDER_NUM);
                for (RecommendedItem ritem : list) {
                    RecommendVo v = new RecommendVo();
                    v.setUserId(userId);
                    v.setShopId((int) ritem.getItemID());
                    v.setScore((double) ritem.getValue());
                    RecommendList.add(v);
                }
                return RecommendList;
            }
        }
        return null;
    }
}
